package com.sigmatrix.h5.aop;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.HttpStatus;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSONObject;
import com.sigmatrix.h5.auth.AuthenticationInfo;
import com.sigmatrix.h5.auth.DisAppAuthenticator;
import com.sigmatrix.h5.auth.IAuthorize;
import com.sigmatrix.h5.auth.LoginSession;
import com.sigmatrix.h5.request.Request;
import com.sigmatrix.h5.response.Response;
import com.sigmatrix.h5.utils.Cons;
import com.sigmatrix.h5.utils.JacksonUtil;
import com.sigmatrix.h5.web.Result;

/**
 * 分销模块 权限拦截。
 * 
 * @author wei.wang
 *
 */
@Aspect
@Component
public class DisAppAuthAspect {
	private static Logger logger = LoggerFactory.getLogger(DisAppAuthAspect.class);
	
	@Autowired
	private DisAppAuthenticator authenticate;
	
	@Autowired
	private IAuthorize authorize;
	

	@Pointcut("execution(* com.sigmatrix.h5.web.controller.*.*(..)) && @annotation(org.springframework.web.bind.annotation.PostMapping)")
	public void auth(){}
	

	@Around(value = "auth()")
	public Object doAuth(ProceedingJoinPoint point) throws Throwable{
		Object[] args = point.getArgs();
		HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); 
		HttpServletResponse response = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
		
		if(args==null){
			return point.proceed();
		}
		for (Object obj : args) {
			if(obj==null){
				continue;
			}
			if(obj instanceof Request){
				Request req = (Request)obj;
				try {
					Signature method = point.getSignature();
					Object target = point.getTarget();
					logger.info("拦截方法：{}", target.getClass().getName()+method.getName());
				} catch (Exception e) {}
				if(!isAccessAllowed(req, request, response)){
					return null;
				}else{
					return point.proceed();
				}
			}
		}
		
		return point.proceed();
		
	}
	
	
	/**
	 * 是否允许访问
	 * 
	 * @param req
	 * @param request
	 * @param response
	 * @return
	 * @throws IOException
	 */
	private boolean isAccessAllowed(Request req,HttpServletRequest request,HttpServletResponse response) throws IOException{
		AuthenticationInfo info = new AuthenticationInfo();
		info.setAcctId(req.getUserId());
		info.setEseCode(req.getEnterpriseCode());
		info.setDealerOrShopId(req.getUserDealerId());
		String token = authenticate.generateToken(info);
		if(!authenticate.isLogin(token)){
			response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
			response.getWriter().write(JacksonUtil.write2JsonString(new Response(Cons.RESPONSE_CODE_SC_UNAUTHORIZED, "请重新登陆")));
			return false;
		}
		LoginSession loginSession = authenticate.getLoginSession(token);
		
		boolean accessAllowed = authorize.isAccessAllowed(request.getRequestURI(), loginSession);
		if(accessAllowed){
			return true;
		}else{
			logger.info("该用户:{}, 权限:{}", loginSession.getInfo().getAcctId(),loginSession.getPermissions());
			response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
			response.getWriter().write(JacksonUtil.write2JsonString(new Response(Cons.RESPONSE_CODE_SC_UNAUTHORIZED, "权限不足")));
			return false;
		}
		
	}
	
	
}
